# 22. 内置函数进阶
# lamda匿名函数
是为了解决一些简单的需求面设计的一句话函数
lambda表示的是匿名函数,不需要用def来声明,一句话就可以声明出一个函数
注意:
- 函数的参数可以有多少,多少参数之间用逗号隔开
- 匿名函数不管多复杂,只能写一行,且逻辑结束直接返回数据
- 返回值和正常的函数一样,可以是任意数据类型
- 他只能使用return来返回数据
语法:函数名 = lambda 参数: 返回值
so = lambda n: n * n
print(so(3))
执行结果:
9
# 查看函数名 name()
匿名函数并不是说一定没有名字,前面的变量就是一个函数名,那为什么说他是匿名呢,原因就是通过__name__查看的时候是没有名字的,统一叫 lambda,在调用的时候没有什么特别之处,跟正常的函数差不多,正常函数调用即可
so = lambda n: n * n
def wo(n):
return n * n
print(so(9))
print(so.__name__)
print(wo(9))
print(wo.__name__)
执行结果:
81
<lambda>
81
wo
# sorted()-排序函数
排序函数,在列表中也有一个内置函数sort(),但这个函数只能对列表类型使用,而sorted是面对所有类型
注意:sorted实际是通过数字来排序的,无论你自定义的排序规则是什么,都要给他数字的结果才能排序
语法格式:
sorted(iterable,key=None,reverse=False)
iterable:可迭代对象,表示要进行排序操作的数据类型需要可迭代的
key:排序规则(排序函数),在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数,根据函数运算的结果进行排序,默认是:为空
reverse:是否倒序:True:倒序,False:正序 ,默认是正序
# 来个简单的排序
so = [1,4,0,5,2,6,8,9,3]
so = sorted(so)
print(so)
执行结果:
[0, 1, 2, 3, 4, 5, 6, 8, 9]
为什么不用写,key跟reverse参数,因为这二个都有默认值,如果不使用系统会默认使用默认值
# 在来个字典排序
so = {1:"江",3:"小",2:"凡"}
so = sorted(so)
print(so)
执行结果:
[1, 2, 3]
如果使用默认的key排序规则,是无法排序字典的value值
# 使用自定义的排序规则
排序规则实际是写好的函数,在把函数名放在key中
so = ["技术部","人力行政部","商业务部","财务内帐外帐部"]
def wo(n):
return len(n)
eo = sorted(so, key=wo)
print(eo)
执行结果:
['技术部', '商业务部', '人力行政部', '财务内帐外帐部']
# 模拟运行机制
模拟上一次实例的sorted运行机制
so = ["技术部","人力行政部","商业务部","财务内帐外帐部"]
def wo(n):
return len(n)
eo = sorted(so, key=wo)
print(eo)
## 内部大概是这样运行的
for i in so:
wo(i)
使用for循环,循环要排序的数据,一个一个拿出来,放在自定好的函数中,得到数字,在进行排序
# 用lambda来使用
so = ["技术部","人力行政部","商业务部","财务内帐外帐部"]
wo = lambda n : len(n)
eo = sorted(so, key=wo)
print(eo)
so = ["技术部","人力行政部","商业务部","财务内帐外帐部"]
eo = sorted(so, key=lambda n : len(n))
print(eo)
执行结果:
['技术部', '商业务部', '人力行政部', '财务内帐外帐部']
['技术部', '商业务部', '人力行政部', '财务内帐外帐部']
# 练习题
最后用练习题来结尾
要求:把下面的学习信息按年龄进行顺序
so = [
{"id":1, "name":"张一","age":"17"},
{"id":2, "name":"王二","age":"20"},
{"id":3, "name":"陈三","age":"18"},
{"id":4, "name":"李四","age":"22"},
{"id":5, "name":"赵五","age":"19"},
{"id":6, "name":"孙六","age":"16"}
]
答案
so = [
{"id":1, "name":"张一","age":"17"},
{"id":2, "name":"王二","age":"20"},
{"id":3, "name":"陈三","age":"18"},
{"id":4, "name":"李四","age":"22"},
{"id":5, "name":"赵五","age":"19"},
{"id":6, "name":"孙六","age":"16"}
]
##第一种
def wo(n):
return n["age"]
for i in sorted(so,key=wo):
print(i)
##第二种
for i in sorted(so,key=lambda n: n["age"]):
print(i)
执行结果:
{'id': 6, 'name': '孙六', 'age': '16'}
{'id': 1, 'name': '张一', 'age': '17'}
{'id': 3, 'name': '陈三', 'age': '18'}
{'id': 5, 'name': '赵五', 'age': '19'}
{'id': 2, 'name': '王二', 'age': '20'}
{'id': 4, 'name': '李四', 'age': '22'}
如果不使用for循环也可以,就会出现一个列表,所有数据都在列表中,看着太乱了
# filter() - 筛选函数
筛选函数,也是要自定义筛选规则
筛选出来结果的是迭代器
语法格式:
filter(function,iterable)
function:用于筛选的函数,在filer中会自动的把iterable中的元素传递给function,然后根据function返回的True或False来判断是否保留此项数据
iterable:可以迭代对象
# 来个简单的筛选
so = [1,2,3,4,5,6,7,8,9]
wo = filter(lambda n: n % 2 == 1,so)
print(list(wo))
执行结果:
[1, 3, 5, 7, 9]
以上实例:筛选出来的结果是迭代器,所以要么用__next__等方式执行,或用list列表函数来执行
# 模拟运行机制
so = [1,2,3,4,5,6,7,8,9]
def eo(n):
return n % 2 == 1
wo = filter(eo,so)
print(list(wo))
## 内部大概运行机制
for i in so:
eo(i)
使用for循环获取要筛选的数据,一个一个在给写好的函数规则筛选,Ture就返回数据,False就过滤数据
# 练习题
最后也来个练习题结尾
要求:将以下的学生信息大于等于20岁的筛选出来
so = [
{"id":1, "name":"张一","age":"17"},
{"id":2, "name":"王二","age":"20"},
{"id":3, "name":"陈三","age":"18"},
{"id":4, "name":"李四","age":"22"},
{"id":5, "name":"赵五","age":"19"},
{"id":6, "name":"孙六","age":"16"}
]
答案
so = [
{"id":1, "name":"张一","age":"17"},
{"id":2, "name":"王二","age":"20"},
{"id":3, "name":"陈三","age":"18"},
{"id":4, "name":"李四","age":"22"},
{"id":5, "name":"赵五","age":"19"},
{"id":6, "name":"孙六","age":"16"}
]
## 第一种
wo = filter(lambda i: int(i["age"]) >= 20,so)
print(list(wo))
## 第二种
for i in filter(lambda i: int(i["age"]) >= 20,so):
print(i)
执行结果:
{'id': 2, 'name': '王二', 'age': '20'}
{'id': 4, 'name': '李四', 'age': '22'}
如果不使用for循环也可以,就会出现一个列表,所有数据都在列表中,看着太乱了
# map() - 映射函数
映射函数
语法格式:
map(function,iterable)
function:可以对可迭代对象中的每一个元素进行映射,分别取执行function
iterable:可以迭代对象
# 来个简单的筛选
计算列表中每个元素的平方,返回新列表
eo = [1,2,3,4,5,6,7,8,9]
def so(n):
return n * n
wo = map(so,eo)
print(list(wo))
执行结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
以上实例:筛选出来的结果是迭代器,所以要么用__next__等方式执行,或用list列表函数来执行
# 用lambda来使用
eo = [1,2,3,4,5,6,7,8,9]
print(list(map(lambda n: n * n ,eo)))
执行结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
# 练习题
最后也来个练习题来结尾
要求:计算以下有个列表中相同位置的数据的和
so = [1,10,20,12,5,7,53]
wo = [8,21,25,10,27,84]
答案
so = [1,10,20,12,5,7,53]
wo = [8,21,25,10,27,84]
print(list(map(lambda i,n: i + n ,so,wo)))
执行结果:
[9, 31, 45, 22, 32, 91]
# 递归函数
递归,递归就是在函数中调用函数的本身的就叫做递归
如果在函数中不断的调用递归,这会让内存无限的生成函数空间来存储,可能会让系统卡死
Python解释器为了解决无限递归,限制了递归次数
在Python官方文档显示递归次数不高于1000,实测是998
递归的应用:可以使用递归来遍历各种树形结构,比如文件系统
# 使用递归来遍历文件系统
# 需要的模块跟函数
# 模块
需要使用os模块来遍历文件系统
# 函数
os.listdir(链接路径)
##获取到当前文件夹中的所有文件目录
os.path.join(旧链接路径,新链接路径)
##拼接文件链接,比如获取到一个文件目录链接,但是下面还有目录,就需要这个函数来把二个链接拼接起来
os.path.isdir(链接路径)
##判断该链接路径是文件目录还是文件,目录为:True,文件为:False
# 遍历文件系统
import os
lo = "E:\so"
def so(ls,n):
wo = os.listdir(ls)
for i in wo:
ll = os.path.join(ls,i)
if os.path.isdir(ll):
print("\t" * n,"L"*n,i)
so(ll,n + 1)
else:
print("\t" * n,"L"*n,i)
so(lo,0)
# 这是一个相对简单的遍历递归
导入os模块
定义要查询的文件路径赋值给变量lo
定义函数,定义二个参数,ls:获取文件路径,n:用于区分显示效果
使用os.listdir()函数,打开该路径显示的内容,并赋值给变量wo
使用for循环来遍历变量wo
使用os.path.join()函数来对参数ls跟循环的i进行拼接,并赋值给变量ll
使用if判断来对os.path.isdir()判断ll 路径是否是目录还是文件
打印,这行不用解释了吧!!!
因判断是目录,那目录下可能会还有文件或目录,那么需要使用递归
如果是文件
打印,这行不用解释了吧!!!
执行函数,传递参数
# 二分查找(算法初始)
二分查找,每次能够排除掉一半的数据,查找的效率非常高,但是局限性比较大,必须是有序序列才可以使用二分查找
简单说,就是掐头结尾取中间. 不停的改变左和右. 间接改变中间
如果是初学者会比较难理解,但是最好能理解-
# 二分查找 - 非递归算法
lst = [11,22,33,44,55,66,77,88,99,123,234,345,456,567,678,789,1111]
so = 77
le = 0
re = len(lst) - 1
eo = 1
while le <= re:
wo = (le + re) // 2
if so > lst[wo]:
le = wo + 1
elif so < lst[wo]:
re = wo - 1
else:
print("查找的内容在该列表的第:",wo,"位")
print("经过第",eo,"算法查找")
break
eo += 1
## 一个很简单的二分查找算法
一个要查找的列表
变量so:要查找的值
变量le:开头值
变量re:结尾值
变量eo:记录循环次数值
while循环,判断le变量是否小于或等于re变量
取中间取,怎么取,把开关值跟结尾值相加在除2,因为要得到整数所以要整除// 在赋值给变量
判断查询值是否大于中间值的元素
如果大于,那就证明要的值在右边,需要对开头值进行位置的重新赋值,切掉左边的数据
使用elif判断查询值是否小于中间值的元素
如果小于,那就证明要的值在左边,需要对结尾值进行位置的重新赋值,切掉右边的数据
如果以上判断都不生效
打印中间值
接下来就不用说明了吧!!!
记录值变量+1,效果每次循环记录
# 二分查找 - 非递归算法 - 找出口
如果要查找的值不在数据列表中,那要怎么办
lst = [11,22,33,44,55,66,77,88,99,123,234,345,456,567,678,789,1111]
so = 77
le = 0
re = len(lst) - 1
eo = 1
while le <= re:
if lst.count(so) == 0:
print(-1)
break
wo = (le + re) // 2
if so > lst[wo]:
le = wo + 1
elif so < lst[wo]:
re = wo - 1
else:
print("查找的内容在该列表的第:",wo,"位")
print("经过第",eo,"算法查找")
break
eo += 1
# 二分查找 - 使用递归
lst = [11,22,33,44,55,66,77,88,99,123,234,345,456,567,678,789,1111]
def so(eo,le,re,n=1):
if le <= re:
wo = (le + re) // 2
if eo > lst[wo]:
le = wo + 1
elif eo < lst[wo]:
re = wo - 1
else:
print("查找的内容在该列表的第:",wo,"位")
print("经过第", n, "算法查找")
return
return so(eo,le,re,n+1)
else:
print(-1)
return
so(77,0,len(lst) - 1)